import { Node, IRectLike, IVec2Like, ISizeLike, v2, Rect, Vec3, screen, UITransform, view, Vec2, ResolutionPolicy } from "cc";

/**
 * 将屏幕坐标系内的点或矩形装换到中心坐标系
 * @explain 屏幕坐标系（OpenGL坐标系）：原点在左下角，x轴向右，y轴向上，为物体自身区域 = Rect(0, 0, 1, 1)
 * @explain 中心坐标系（物体坐标系）：原点在中心点，x轴向右，y轴向上，为物体自身区域 = Rect(-0.5, -0.5, 1, 1)
 * @param arg 点或矩形
 * @param out 被赋值得点或矩形，默认新建
 * @param flipY 是否倒转纵坐标视原点在左上角，x轴向右，y轴向下（CSS坐标系）
 * @param size 坐标系尺寸，默认视为已归一化
 * @param magnify 是否对结果放大倍数
 * @return 点或矩形自身
*/
export function convertCenter<T extends (IVec2Like | IRectLike)>(arg: T, out?: T, flipY?: boolean, size?: ISizeLike, magnify?: ISizeLike): T {
    const { width, height } = size ?? _rect;
    const params = { x: (arg.x / width - 0.5) * width, y: (arg.y / height - 0.5) * height };
    if (flipY) params.y = -params.y;
    if (_isRect(arg)) assign(params, <IRectLike>arg, true, 'width', 'height');
    return _convert(out, params, magnify) as T;
}

/**
 * 将中心坐标系的点或矩形装换到屏幕坐标系内
 * @explain 屏幕坐标系（物体坐标系）：原点在左上角，x轴向右，y轴向下，为物体自身区域 = Rect(0, 0, 1, 1)
 * @explain 中心坐标系（OpenGL坐标系）：原点在中心点，x轴向右，y轴向上，为物体自身区域 = Rect(-0.5, -0.5, 1, 1)
 * @param arg 点或矩形
 * @param out 被赋值得点或矩形，默认新建
 * @param flipY 是否倒转纵坐标视原点在左上角，x轴向右，y轴向下（CSS坐标系）
 * @param size 坐标系尺寸，默认视为已归一化
 * @param magnify 是否对结果放大倍数
 * @return 点或矩形自身
*/
export function convertScreen<T extends (IVec2Like | IRectLike)>(arg: T, out?: T, flipY: boolean = false, size?: ISizeLike, magnify?: ISizeLike): T {
    const { width, height } = size ?? _rect;
    const params = { x: (arg.x / width + 0.5) * width, y: (arg.y / height + 0.5) * height };
    if (flipY) params.y = height - params.y;
    if (_isRect(arg)) assign(params, <IRectLike>arg, true, 'width', 'height');
    return _convert(out, params, magnify) as T;
}

// 坐标转换
function _convert(out: IVec2Like | IRectLike, params: object, magnify?: ISizeLike): IVec2Like | IRectLike {
    const ret = out ?? (_isRect(params) ? new Rect : v2());
    assign(ret, params, true);
    if (magnify) {
        const { width, height } = magnify;
        ret.x *= width; ret.y *= height;
        if (_isRect(ret)) { ret.width *= width; ret.height *= height; }
    }
    return ret;
}

// 判断是否为矩形
function _isRect(arg: any): arg is IRectLike {
    return isNum(arg.width) && isNum(arg.height);
}

/**
 * 将UI节点置顶
 * @param node 目标节点
*/
export function setTop(node: Node): void {
    if (!node.parent) return;
    node.setSiblingIndex(node.parent.children.length - 1);
}

/**
 * 将UI节点置次顶
 * @param node 目标节点
*/
export function setSecondTop(node: Node): void {
    if (!node.parent) return;
    node.setSiblingIndex(node.parent.children.length - 2);
}

/**
 * 将UI节点置底
 * @param node 目标节点
*/
export function setBottom(node: Node): void {
    if (!node.parent) return;
    node.setSiblingIndex(0);
}

/**
 * TODO 绘制跨域头像
 * 获得UI节点在页面上的CSS样式
 * @param uit 目标节点的UITransform
 * @return 位置和大小样式
*/
export function getCSSStyleRect(uit: UITransform): Rect {
    const { devicePixelRatio: dpr } = screen;
    let { width: devW, height: devH } = view.getVisibleSizeInPixel();
    let { width: disW } = view.getDesignResolutionSize();
    devW /= dpr; devH /= dpr;
    const ratio = devW / disW;
    let { width: w, height: h, anchorX, anchorY } = uit;
    let { x, y } = uit.node.worldPosition;
    w *= ratio; h *= ratio;
    x *= ratio; y *= ratio;
    x -= (anchorX * w);
    y = devH - y + (1 - anchorY) * w;
    return new Rect(x, y, w, h);
}

const _rect = new Rect(0, 0, 1, 1);